package com.example.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mapper.OrderMapper;
import com.example.mapper.PayedOrderMapper;
import com.example.mapper.ShippingMapper;
import com.example.model.dto.OrderDTO;
import com.example.model.dto.Result;
import com.example.model.entity.Order;
import com.example.model.entity.PayedOrder;
import com.example.model.entity.Shipping;
import com.example.model.vo.*;
import com.example.service.ICartService;
import com.example.service.IOrderService;
import com.example.service.IShopService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.sql.Date;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @program: backend
 * @author: zk
 * @create: 2023-04-23 20:26
 **/
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {
    @Resource
    private HttpSession session;

    @Resource
    private ICartService cartService;

    @Resource
    private ShippingMapper shippingMapper;

    @Resource
    private PayedOrderMapper payedOrderMapper;

    @Resource
    private PayedOrderServiceImpl payedOrderService;

    @Resource
    private IShopService shopService;

    @Override
    public Result createOrder(OrderDTO orderDTO, HttpServletRequest request) {

        if (orderDTO.getShippingId() <= 0) {
            return Result.fail("输入信息有误");
        }

        // 1.获取用户信息
        UserVO user = (UserVO) session.getAttribute("user");

        // 2.获取用户id
        String userId = user.getId();

        // 3.根据用户id查询用户购物车信息
        Result carts = cartService.getCarts(request);
        CartsVO data = (CartsVO) carts.getData();
        List<CartVO> list = data.getCartProductVoList();

        // 4.计算购物车中选中商品的总价值
        int count = 0;

        // 生成产品信息列表
        ArrayList<ShopListVO> shopListVO = new ArrayList<>();

        HashMap<Long, Integer> payedMap = new HashMap<>();
        for (CartVO product : list) {
            // 4.1购物车中商品状态为选中状态
            if (product.isProductSelected()) {
                // 4.2商品价格计算
                count += (product.getQuantity() * product.getProductPrice());

                //保存已支付产品的id和数量
                payedMap.put(product.getProductId(), product.getQuantity());

                // 4.3封装产品信息
                ShopListVO slVO = new ShopListVO();
                slVO.setProductId((long) product.getProductId());
                slVO.setProductName(product.getProductName());
                slVO.setQuantity(product.getQuantity());
                slVO.setProductImage(product.getProductMainImage());
                slVO.setCurrentUnitPrice(product.getProductPrice());
                slVO.setTotalPrice(product.getProductTotalPrice());
                // 4.4将产品信息添加到产品信息列表
                shopListVO.add(slVO);
            }
        }
        if (count == 0) {
            return Result.fail("未有选中要支付的产品");
        }

        // 创建订单对象
        Order order = new Order();
        order.setPayment(count);
        order.setStatus(orderDTO.getStatus());

        // 5.生成订单时间
        Date date = new Date(new java.util.Date().getTime());
        order.setCreateTime(date);
        order.setPaymentTime(date);



        order.setShippingId(orderDTO.getShippingId());
        order.setUserId(userId);

        // 6.1 保存订单信息
/*        // 6.1.1 判断数据库中是否存在相同数据
        QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper
                .eq("payment", order.getPayment())
                .eq("status", order.getStatus())
                .eq("paymentTime", order.getPaymentTime())
                .eq("createTime", order.getCreateTime())
                .eq("userId", order.getUserId());
        Integer cntOrder = orderMapper.selectCount(orderQueryWrapper);
        // 6.1.2不存在
        if (cntOrder == 0) {*/

        // 保存
        save(order);

        /*    // 保存失败
            if (!save) {
                return Result.fail("创建订单失败");
            }
        }*/

        // 7.查询订单编号
        Order order1 = this.getOne(new LambdaQueryWrapper<Order>().orderByDesc(Order::getOrderNo).last("limit 1"));

        // 9.保存支付订单信息
        try {
            for (Long pId : payedMap.keySet()) {
                // 9.2创建已支付的订单信息对象
                PayedOrder po = new PayedOrder();
                // 9.3设置已支付订单信息
                po.setProductId(pId);
                po.setQuantity(payedMap.get(pId));
                po.setUserId(userId);
                po.setOrderNo(order1.getOrderNo());
                po.setShippingId(orderDTO.getShippingId());
                // 9.4保存
                payedOrderMapper.insert(po);
            }
        } catch (Exception e) {
            throw new RuntimeException("保存已支付产品信息失败");
        }

        // 10.创建封装信息对象
        CreateOrderVO createOrderVO = new CreateOrderVO();

        // 11.封装订单信息
        createOrderVO.setOrderNo(order1.getOrderNo() + 1);
        createOrderVO.setPayment(count);
        createOrderVO.setStatus(orderDTO.getStatus());
        createOrderVO.setPaymentTime(order.getPaymentTime());
        createOrderVO.setCreateTime(order.getCreateTime());

        // 12.封装订单中产品信息
        createOrderVO.setOrderItemVoList(shopListVO);

        // 13.封装收货人信息
        Shipping shipping = shippingMapper.selectById(orderDTO.getShippingId());
        OrderShippingVO orderShippingVO = BeanUtil.copyProperties(shipping, OrderShippingVO.class);

        // 14.将收货人信息添加到订单信息中
        createOrderVO.setOrderShippingVO(orderShippingVO);

        // 15.返回订单信息
        return Result.ok(createOrderVO);
    }

    @Override
    public Result getOrder() {
        // 1.获取用户id
        UserVO user = (UserVO) session.getAttribute("user");
        String userId = user.getId();

        // 2.创建返回对象
        OrderListVO orderListVO = new OrderListVO();

        // 3.根据用户id查询用户的所有账单信息
        List<Order> userOrderList = query().eq("userId", userId).list();

        // 4.根据用户查询已付款的账单信息
        List<PayedOrder> userPayedOrder = payedOrderService.getByUserId();

        List<CreateOrderVO> createOrderListVO = new ArrayList<CreateOrderVO>();

        // 5.设置返回参数
        for (Order order : userOrderList) {
            // 5.1创建订单信息对象
            CreateOrderVO createOrderVO = new CreateOrderVO();

            // 5.2获取订单id
            Long orderNo = order.getOrderNo();

            // 5.3封装订单的基础信息
            createOrderVO.setOrderNo(orderNo);
            createOrderVO.setPayment(order.getPayment());
            createOrderVO.setStatus(order.getStatus());
            createOrderVO.setPaymentTime(order.getPaymentTime());

            // 5.4创建订单中的商品信息列表
            List<ShopListVO> shopListVOS = new ArrayList<>();

            // 5.5获取该已支付订单的产品id和数量
            for (PayedOrder payedOrder : userPayedOrder) {
                ShopListVO shopVO = new ShopListVO();
                if (payedOrder.getOrderNo() == orderNo) {
                    // 5.5.1根据产品id查询产品的基本信息
                    Result data = shopService.getShop(payedOrder.getProductId() + "");
                    ShopDetailVO shop = (ShopDetailVO) data.getData();

                    // 5.5.2封装产品信息
                    shopVO.setProductId(shop.getId());
                    shopVO.setProductName(shop.getName());
                    shopVO.setProductImage(shop.getMainImage());
                    shopVO.setCurrentUnitPrice(shop.getPrice());
                    shopVO.setQuantity(payedOrder.getQuantity());
                    shopVO.setTotalPrice(shop.getPrice() * payedOrder.getQuantity());

                    // 5.5.3将商品信息添加到商品信息列表
                    shopListVOS.add(shopVO);
                }
            }
            // 5.6将商品列表信息添加到返回信息的对象中
            createOrderVO.setOrderItemVoList(shopListVOS);

            // 5.7查询对应订单的地址信息
            Shipping shipping = shippingMapper.selectById(order.getShippingId());
            // 5.8获取收货人信息
            OrderShippingVO orderShippingVO = BeanUtil.copyProperties(shipping, OrderShippingVO.class);

            //5.9封装收货人信息
            createOrderVO.setOrderShippingVO(orderShippingVO);

            //5.10将订单信息添加到订单信息列表中
            createOrderListVO.add(createOrderVO);

        }

        //6.封装成前端需要的信息
        orderListVO.setList(createOrderListVO);

        // 6返回信息
        return Result.ok(orderListVO);
    }
}
